package com.zdsoft.site.mina.p2p;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hundsun.encrypt.Mac;
import com.hundsun.encrypt.util.EncryptUtil;
import com.hundsun.encrypt.util.HsParam;
import com.zdsoft.site.mina.codec.P2PFilter;
import com.zdsoft.site.mina.codec.P2PStringCodecFactory;
import com.zdsoft.site.mina.model.PackageHeader;
import com.zdsoft.site.mina.model.request.AbstractRequest;
import com.zdsoft.site.mina.model.response.AbstractResponse;

public abstract class P2PIoHandler  extends IoHandlerAdapter{
	
	protected Logger logger=LoggerFactory.getLogger(getClass());
	private AbstractResponse response;
	public static String macKey="9FBC0E74029CD8E8";
	public static String pinKey="BF41DB639F6B3FC8";
	public static String pkgKey="BF41DB639F6B3FC86B303EE83537F698BF41DB639F6B3FC8";
	public static String exchangeKey = "handsome";
	
	protected final SocketConnector connector;	
	
	protected final AbstractRequest request;
	
	/**默认读取缓存的大小*/
	public static final int BufferSize=2048;
    /**
     * @param message 需要发送的消息体
     */
	public P2PIoHandler(AbstractRequest request){
		this.request=request;//发送的参数
		connector=new NioSocketConnector();
		connector.setHandler(this);
		connector.getFilterChain().addLast("logger", new LoggingFilter());
		connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new P2PStringCodecFactory(Charset.forName("GBK"))));
		
		connector.getFilterChain().addLast("p2p", new P2PFilter());
		connector.setHandler(this);
		
		connector.getSessionConfig().setReadBufferSize(BufferSize);//8192
		//connector.getSessionConfig().setKeepAlive(false);
		ConnectFuture cf = connector.connect(new InetSocketAddress("120.55.174.14", 8015));
		//ConnectFuture cf = connector.connect(new InetSocketAddress("127.0.0.1", 8015));
		cf.awaitUninterruptibly();
		IoSession session=cf.getSession();
		//session.write(IoBuffer.wrap((message).getBytes()));
		//logger.debug("调用write方法发送数据");
		//session.write(message);
		session.getCloseFuture().awaitUninterruptibly();
		connector.dispose();
	}
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		logger.debug("打开会话:{}",getInstrCd());
		//包头信息
		PackageHeader pkghdr=new PackageHeader();
    	pkghdr.setInstId(getInstId());
    	pkghdr.setInstrCd(getInstrCd());
    	pkghdr.setFlag("012");
    	//包体信息
    	request.getMsgHdr().setInstrCd(getInstrCd());
    	request.getMsgHdr().getSvInst().setInstId(getInstId());
    	request.getMsgHdr().getRqRef().setRefIssr(getInstId());
    	
    	String message=request.toXml();
    	pkghdr.setMac(Mac.generateMAC(HsParam.HS_ENC, message,macKey));
    	String text=EncryptUtil.pkgEnc(message,pkgKey,exchangeKey);
    	
    	pkghdr.setBodyLength(text.getBytes("GBK").length);
    	session.setAttribute("pkghdr", pkghdr);
    	logger.debug("1.0.打开会话发送报文:{}{}",pkghdr,message);
    	session.write(pkghdr+text);
    	
	}
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		logger.debug("创建会话:{}",getInstrCd());
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		logger.debug("会话关闭:{}",getInstrCd());
	}
	
	@Override
	public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
		logger.debug("会话空闲:{}",getInstrCd());
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		logger.debug("操作异常={}",cause.getMessage());
		cause.printStackTrace();
	}
	
	@Override
	public void inputClosed(IoSession session) throws Exception {
		super.inputClosed(session);
		logger.debug("inputClosed");
	}
	/**
	 * 获取交易类型
	 **/
	public abstract String getInstrCd();
	
	public String getInstId(){
		return "P8888000";
	}
	
	/**请求的参数*/
	public AbstractRequest getRequest() {
		return request;
	}
	
	/**响应的参数*/
	public AbstractResponse getResponse() {
		return response;
	}
	
	/**响应的参数*/
	public void setResponse(AbstractResponse response) {
		this.response = response;
	}
}
